package com.castle.fortress.admin.cms.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.castle.fortress.admin.cms.dto.*;
import com.castle.fortress.admin.cms.entity.CmsArticleEntity;
import com.castle.fortress.admin.cms.mapper.CmsArticleMapper;
import com.castle.fortress.admin.cms.service.*;
import com.castle.fortress.admin.system.entity.SysUser;
import com.castle.fortress.admin.utils.BizCommonUtil;
import com.castle.fortress.common.enums.ViewFormTypeEnum;
import com.castle.fortress.common.enums.YesNoEnum;
import com.castle.fortress.common.utils.ConvertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * cms内容管理表 服务实现类
 *
 * @author castle
 * @since 2022-03-10
 */
@Service
public class CmsArticleServiceImpl extends ServiceImpl<CmsArticleMapper, CmsArticleEntity> implements CmsArticleService {
    @Autowired
    private CmsModelService cmsModelService;
    @Autowired
    private CmsColConfigService cmsColConfigService;
    @Autowired
    private CmsModelDataService cmsModelDataService;
    @Autowired
    private CmsArticleTagsService cmsArticleTagsService;
    @Autowired
    private CmsArticleSubjectService cmsArticleSubjectService;
    @Autowired
    private CmsSysTagService cmsSysTagService;
    @Autowired
    private CmsCustTagService cmsCustTagService;

    /**
    * 获取查询条件
    * @param cmsArticleDto
    * @return
    */
    public QueryWrapper<CmsArticleEntity> getWrapper(CmsArticleDto cmsArticleDto){
        QueryWrapper<CmsArticleEntity> wrapper= new QueryWrapper();
        if(cmsArticleDto != null){
            CmsArticleEntity cmsArticleEntity = ConvertUtil.transformObj(cmsArticleDto,CmsArticleEntity.class);
            wrapper.like(cmsArticleEntity.getId() != null,"id",cmsArticleEntity.getId());
            wrapper.like(StrUtil.isNotEmpty(cmsArticleEntity.getTitle()),"title",cmsArticleEntity.getTitle());
            wrapper.like(StrUtil.isNotEmpty(cmsArticleEntity.getContents()),"contents",cmsArticleEntity.getContents());
            wrapper.like(StrUtil.isNotEmpty(cmsArticleEntity.getAuthor()),"author",cmsArticleEntity.getAuthor());
            wrapper.like(StrUtil.isNotEmpty(cmsArticleEntity.getKeywords()),"keywords",cmsArticleEntity.getKeywords());
            wrapper.like(StrUtil.isNotEmpty(cmsArticleEntity.getPublisher()),"publisher",cmsArticleEntity.getPublisher());
            wrapper.eq(cmsArticleEntity.getStatus() != null,"status",cmsArticleEntity.getStatus());
            wrapper.orderByDesc("create_time");
        }
        return wrapper;
    }


    @Override
    public IPage<CmsArticleDto> pageCmsArticle(Page<CmsArticleDto> page, CmsArticleDto cmsArticleDto) {
        QueryWrapper<CmsArticleEntity> wrapper = getWrapper(cmsArticleDto);
        Page<CmsArticleEntity> pageEntity = new Page(page.getCurrent(), page.getSize());
        Page<CmsArticleEntity> cmsArticlePage=baseMapper.selectPage(pageEntity,wrapper);
        Page<CmsArticleDto> pageDto = new Page(cmsArticlePage.getCurrent(), cmsArticlePage.getSize(),cmsArticlePage.getTotal());
        pageDto.setRecords(ConvertUtil.transformObjList(cmsArticlePage.getRecords(),CmsArticleDto.class));
        return pageDto;
    }

	@Override
	public IPage<CmsArticleDto> pageCmsArticleExtends(Page<CmsArticleDto> page, CmsArticleDto cmsArticleDto,List<Long> roldIds){
		Map<String,Long> pageMap = BizCommonUtil.getPageParam(page);
          CmsArticleEntity cmsArticleEntity = ConvertUtil.transformObj(cmsArticleDto,CmsArticleEntity.class);
		List<CmsArticleEntity> cmsArticleList=baseMapper.extendsList(pageMap,cmsArticleEntity,roldIds);
		Long total = baseMapper.extendsCount(cmsArticleEntity,roldIds);
		Page<CmsArticleDto> pageDto = new Page(page.getCurrent(), page.getSize(),total);
		pageDto.setRecords(ConvertUtil.transformObjList(cmsArticleList,CmsArticleDto.class));
		return pageDto;
	}
	@Override
	public CmsArticleDto getByIdExtends(Long id){
          CmsArticleEntity  cmsArticleEntity = baseMapper.getByIdExtends(id);
        CmsArticleDto dto = ConvertUtil.transformObj(cmsArticleEntity,CmsArticleDto.class);
        List<Long> attr=new ArrayList<>();
        List<Object> tags=new ArrayList<>();
        //获取属性信息
        CmsArticleTagsDto tagsDto = new CmsArticleTagsDto();
        tagsDto.setArticleId(id);
        List<CmsArticleTagsDto> tagsDtos=cmsArticleTagsService.listCmsArticleTags(tagsDto);
        for(CmsArticleTagsDto d:tagsDtos){
            //文章属性
            if("00".equals(d.getTagType())){
                attr.add(d.getTagId());
            //文章标签
            }else if("01".equals(d.getTagType())){
                tags.add(d.getTagId());
            }
        }
        dto.setAttr(attr);
        dto.setTags(tags);
        //专题
        List<Long> special = new ArrayList<>();
        CmsArticleSubjectDto querySub = new CmsArticleSubjectDto();
        querySub.setArticleId(id);
        List<CmsArticleSubjectDto> subjectDtos = cmsArticleSubjectService.listCmsArticleSubject(querySub);
        for(CmsArticleSubjectDto d:subjectDtos){
            special.add(d.getSubjectId());
        }
        dto.setSpecial(special);
        //获取文章模型
        CmsModelDto modelDto =cmsModelService.getByArticleId(id);
        if(modelDto == null){
            return null;
        }
        //获取扩展模型字段
        if(YesNoEnum.YES.getCode().equals(modelDto.getIsExtend())){
            List<CmsColConfigDto> list = cmsColConfigService.listByChannel(cmsArticleEntity.getChannelId());
            //获取扩展字段的数据
            Map<String, Object> map = cmsModelDataService.queryById(modelDto.getCode(),id.toString());
            if(map == null){
                map = new HashMap<>();
                //特殊字段处理
                for(CmsColConfigDto d:list){
                    map.put(d.getPropName(),null);
                }
                map.put("id",id);
            }
            //特殊字段处理
            for(CmsColConfigDto d:list){
                //多图片
                if(ViewFormTypeEnum.IMAGE_UPLOAD.getCode().equals(d.getFormType()) && d.getLimitSize()>1 && map.get(d.getPropName())!=null){
                    map.put(d.getPropName(),map.get(d.getPropName()).toString().split(","));
                }
                //文件
                if(ViewFormTypeEnum.FILE_UPLOAD.getCode().equals(d.getFormType()) && map.get(d.getPropName())!=null){
                    JSONArray files= new JSONArray(map.get(d.getPropName()));
                    List<Map<String,String>> f= new ArrayList<>();
                    for(int i=0;i<files.size();i++){
                        JSONObject o= files.getJSONObject(i);
                        Map<String,String> m = new HashMap<>();
                        m.put("name",o.getStr("name"));
                        m.put("url",o.getStr("url"));
                        f.add(m);
                    }
                    map.put(d.getPropName(),f);
                }
                //文件
                if(ViewFormTypeEnum.CHECK_BOX.getCode().equals(d.getFormType()) && map.get(d.getPropName())!=null){
                    if(map.get(d.getPropName())==null || StrUtil.isEmpty(map.get(d.getPropName()).toString())){
                        map.put(d.getPropName(),new ArrayList<>());
                    }else{
                        map.put(d.getPropName(),map.get(d.getPropName()).toString().split(","));
                    }
                }
                //日期
                if(ViewFormTypeEnum.DATE.getCode().equals(d.getFormType()) && map.get(d.getPropName())!=null){
                    map.put(d.getPropName(), map.get(d.getPropName()).toString());
                }
                //日期时间
                if(ViewFormTypeEnum.DATE_TIME.getCode().equals(d.getFormType()) && map.get(d.getPropName())!=null){
                    map.put(d.getPropName(), DateUtil.format((Date)map.get(d.getPropName()),"yyyy-MM-dd HH:mm:ss"));
                }
            }
            dto.setColData(map);
        }
		return dto;
	}

    @Override
    public List<CmsArticleDto> listCmsArticle(CmsArticleDto cmsArticleDto){
        QueryWrapper<CmsArticleEntity> wrapper = getWrapper(cmsArticleDto);
        List<CmsArticleEntity> list = baseMapper.selectList(wrapper);
        return ConvertUtil.transformObjList(list,CmsArticleDto.class);
    }

    @Override
    public List<CmsArticleDto> listByChannel(String code) {
        List<CmsArticleEntity> list = baseMapper.listByChannel(code);
        return ConvertUtil.transformObjList(list,CmsArticleDto.class);
    }

    @Override
    public List<CmsArticleDto> listBySubject(String code) {
        List<CmsArticleEntity> list = baseMapper.listBySubject(code);
        return ConvertUtil.transformObjList(list,CmsArticleDto.class);
    }

    @Override
    public List<CmsArticleDto> listByTag(String title) {
        List<CmsArticleEntity> list = baseMapper.listByTag(title);
        return ConvertUtil.transformObjList(list,CmsArticleDto.class);
    }

    @Override
    public List<Map<String,Object>> cmsTagChannelCmsArticle(Map<String, Object> map) {
        return baseMapper.cmsTagChannelCmsArticle(map);
    }

    @Override
    public Integer cmsTagCountChannelCmsArticle(Map<String, Object> map) {
        return baseMapper.cmsTagCountChannelCmsArticle(map);
    }

    @Override
    public List<CmsArticleDto> cmsTagSpecialCmsArticle(Map<String, Object> map) {
        return ConvertUtil.transformObjList(baseMapper.cmsTagSpecialCmsArticle(map),CmsArticleDto.class);
    }

    @Override
    public Integer cmsTagCountSpecialCmsArticle(Map<String, Object> map) {
        return baseMapper.cmsTagCountSpecialCmsArticle(map);
    }

    @Override
    public List<CmsArticleDto> cmsTagTagCmsArticle(Map<String, Object> map) {
        return ConvertUtil.transformObjList(baseMapper.cmsTagTagCmsArticle(map),CmsArticleDto.class);
    }

    @Override
    public Integer cmsTagCountTagCmsArticle(Map<String, Object> map) {
        return baseMapper.cmsTagCountTagCmsArticle(map);
    }

    @Override
    public CmsArticleDto cmsTagInfo(Long id) {
        CmsArticleDto dto = cmsTagGtByIdExtends(id);
        if(dto==null || YesNoEnum.YES.getCode().equals(dto.getIsDeleted())){
            return null;
        }else{
            return dto;
        }
    }

    @Override
    public List<CmsArticleDto> cmsTagSearchCmsArticle(Map<String, Object> map) {
        return ConvertUtil.transformObjList(baseMapper.cmsTagSearchCmsArticle(map),CmsArticleDto.class);
    }

    @Override
    public Integer cmsTagCountSearchCmsArticle(Map<String, Object> map) {
        return baseMapper.cmsTagCountSearchCmsArticle(map);
    }

    @Override
    public CmsArticleDto cmsTagGtByIdExtends(Long id) {
        CmsArticleEntity  cmsArticleEntity = baseMapper.getByIdExtends(id);
        CmsArticleDto dto = ConvertUtil.transformObj(cmsArticleEntity,CmsArticleDto.class);
        //获取属性信息
        List<CmsSysTagDto> attrInfos=cmsSysTagService.listCmsSysTagByAtri(id);
        dto.setAttrInfos(attrInfos);
        //获取自定义标签信息
        List<CmsCustTagDto> tagInfos=cmsCustTagService.listByArticle(id);
        dto.setTagInfos(tagInfos);
        //专题
        List<Long> special = new ArrayList<>();
        CmsArticleSubjectDto querySub = new CmsArticleSubjectDto();
        querySub.setArticleId(id);
        List<CmsArticleSubjectDto> subjectDtos = cmsArticleSubjectService.listCmsArticleSubject(querySub);
        for(CmsArticleSubjectDto d:subjectDtos){
            special.add(d.getSubjectId());
        }
        dto.setSpecial(special);
        //获取文章模型
        CmsModelDto modelDto =cmsModelService.getByArticleId(id);
        if(modelDto == null){
            return null;
        }
        //获取扩展模型字段
        if(YesNoEnum.YES.getCode().equals(modelDto.getIsExtend())){
            List<CmsColConfigDto> list = cmsColConfigService.listByChannel(cmsArticleEntity.getChannelId());
            //获取扩展字段的数据
            Map<String, Object> map = cmsModelDataService.queryById(modelDto.getCode(),id.toString());
            if(map == null){
                map = new HashMap<>();
                //特殊字段处理
                for(CmsColConfigDto d:list){
                    map.put(d.getPropName(),null);
                }
                map.put("id",id);
            }
            //特殊字段处理
            for(CmsColConfigDto d:list){
                //多图片
                if(ViewFormTypeEnum.IMAGE_UPLOAD.getCode().equals(d.getFormType()) && d.getLimitSize()>1 && map.get(d.getPropName())!=null){
                    map.put(d.getPropName(),map.get(d.getPropName()).toString().split(","));
                }
                //文件
                if(ViewFormTypeEnum.FILE_UPLOAD.getCode().equals(d.getFormType()) && map.get(d.getPropName())!=null){
                    JSONArray files= new JSONArray(map.get(d.getPropName()));
                    List<Map<String,String>> f= new ArrayList<>();
                    for(int i=0;i<files.size();i++){
                        JSONObject o= files.getJSONObject(i);
                        Map<String,String> m = new HashMap<>();
                        m.put("name",o.getStr("name"));
                        m.put("url",o.getStr("url"));
                        f.add(m);
                    }
                    map.put(d.getPropName(),f);
                }
                //日期
                if(ViewFormTypeEnum.DATE.getCode().equals(d.getFormType()) && map.get(d.getPropName())!=null){
                    map.put(d.getPropName(), map.get(d.getPropName()).toString());
                }
                //日期时间
                if(ViewFormTypeEnum.DATE_TIME.getCode().equals(d.getFormType()) && map.get(d.getPropName())!=null){
                    map.put(d.getPropName(), DateUtil.format((Date)map.get(d.getPropName()),"yyyy-MM-dd HH:mm:ss"));
                }

            }
            dto.setColData(map);
        }
        return dto;
    }

    @Override
    public IPage<CmsArticleDto> pageAudit(Page<CmsArticleDto> page, CmsArticleDto cmsArticleDto, SysUser user) {
        Map<String,Long> pageMap = BizCommonUtil.getPageParam(page);
        CmsArticleEntity cmsArticleEntity = ConvertUtil.transformObj(cmsArticleDto,CmsArticleEntity.class);
        Long userId=user.getId();
        //超管看所有审核文章
        if(user.getIsAdmin()){
            userId = null;
        }
        List<CmsArticleEntity> cmsArticleList=baseMapper.extendsAuditList(pageMap,cmsArticleEntity,userId);
        Long total = baseMapper.extendsAuditCount(cmsArticleEntity,userId);
        Page<CmsArticleDto> pageDto = new Page(page.getCurrent(), page.getSize(),total);
        pageDto.setRecords(ConvertUtil.transformObjList(cmsArticleList,CmsArticleDto.class));
        return pageDto;
    }

    @Override
    public boolean moveChannel(List<Long> ids, Long channelId) {
        return baseMapper.moveChannel(ids,channelId)>0;
    }

    @Override
    public boolean toDrafts(List<Long> ids) {
        return baseMapper.toDrafts(ids)>0;
    }

    @Override
    public boolean toDelReal(List<Long> ids) {
        return baseMapper.toDelReal(ids)>0;
    }

    @Override
    public boolean toGarbage(List<Long> ids) {
        return baseMapper.toGarbage(ids)>0;
    }

    @Override
    public void cancelAudit(Long channelId) {
        baseMapper.cancelToPub(channelId);
        baseMapper.cancelToDrafts(channelId);
    }
}

